package gui;

import gui.input.engineer.EditDataDialog;
import gui.input.manager.ProjectCharacteristicsDialog;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.observable.list.WritableList;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.StatusLineManager;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.databinding.viewers.ObservableListTreeContentProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.wb.rcp.databinding.BeansListObservableFactory;
import org.eclipse.wb.rcp.databinding.TreeBeanAdvisor;
import org.eclipse.wb.rcp.databinding.TreeObservableLabelProvider;

import data.TreeViewElement;
import data.model.OverviewProjectsCollection;
import data.model.Project;
import data.model.ProjectCharacteristics;
import data.model.ProjectWeek;
import data.model.ProjectsCollection;

public class MainWindow extends ApplicationWindow {
	private DataBindingContext m_bindingContext;
	private final ProjectsCollection projectsCollection;
	private final ProjectCharacteristics projectHealthCriteria;
	private TreeViewer treeViewer;
	private Action action;
	private Composite composite;
	private Action action_1;

	/**
	 * Create the application window.
	 */
	public MainWindow(ProjectsCollection projectsCollection) {
		super(null);
		this.projectsCollection = projectsCollection;
		this.projectHealthCriteria = new ProjectCharacteristics(50, 5, 100000,
				15, 50, 99, 80);
		createActions();
		// addToolBar(SWT.FLAT | SWT.WRAP);
		addMenuBar();
		// addStatusLine();
	}

	/**
	 * Create contents of the application window.
	 * 
	 * @param parent
	 */
	@Override
	protected Control createContents(Composite parent) {
		final Composite container = new Composite(parent, SWT.NONE);
		container.setLayout(new GridLayout(2, false));

		treeViewer = new TreeViewer(container, SWT.BORDER);
		treeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
			@Override
			public void selectionChanged(SelectionChangedEvent event) {
				if (!event.getSelection().isEmpty()) {
					if (event.getSelection() instanceof IStructuredSelection) {
						if (composite != null
								&& composite.isDisposed() == false) {
							composite.dispose();
						}
						IStructuredSelection selection = (IStructuredSelection) event
								.getSelection();
						Object selectedObject = selection.getFirstElement();
						// Projekt
						if (selectedObject instanceof Project) {
							Project project = (Project) selectedObject;
							composite = new ProjectComposite(container,
									SWT.NONE, project, projectHealthCriteria);
							composite.setLayoutData(new GridData(SWT.LEFT,
									SWT.TOP, true, true, 1, 1));
						}
						// ProjectWeek
						else if (selectedObject instanceof ProjectWeek) {
							ProjectWeek projectWeek = (ProjectWeek) selectedObject;
							composite = new ProjectWeekComposite(container,
									SWT.NONE, projectWeek);
						}
						// Overview
						else {
							composite = new OverviewComposite(container,
									SWT.NONE, projectsCollection,
									projectHealthCriteria);
						}
						composite.setLayoutData(new GridData(SWT.LEFT, SWT.TOP,
								true, true));

						container.layout(true);
					}
				}
			}
		});
		treeViewer.setAutoExpandLevel(2);
		Tree tree = treeViewer.getTree();
		tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true, 1, 1));

		m_bindingContext = initDataBindings();

		return container;
	}

	/**
	 * Create the actions.
	 */
	private void createActions() {
		// Create the actions
		{
			action = new Action("Engineer: &Enter Effort Data") {

				/*
				 * (non-Javadoc)
				 * 
				 * @see org.eclipse.jface.action.Action#run()
				 */
				@Override
				public void run() {
					new EditDataDialog(composite, getShell(),
							projectsCollection).open();
				}

			};
		}
		{
			action_1 = new Action("Manager: Define &Health Criteria") {
				@Override
				public void run() {
					new ProjectCharacteristicsDialog(composite, getShell(),
							projectHealthCriteria).open();
				}
			};
		}
	}

	/**
	 * Create the menu manager.
	 * 
	 * @return the menu manager
	 */
	@Override
	protected MenuManager createMenuManager() {
		MenuManager menuManager = new MenuManager("menu");
		menuManager.add(action);
		menuManager.add(action_1);
		return menuManager;
	}

	/**
	 * Create the toolbar manager.
	 * 
	 * @return the toolbar manager
	 */
	@Override
	protected ToolBarManager createToolBarManager(int style) {
		ToolBarManager toolBarManager = new ToolBarManager(style);
		return toolBarManager;
	}

	/**
	 * Create the status line manager.
	 * 
	 * @return the status line manager
	 */
	@Override
	protected StatusLineManager createStatusLineManager() {
		StatusLineManager statusLineManager = new StatusLineManager();
		return statusLineManager;
	}

	/**
	 * Configure the shell.
	 * 
	 * @param newShell
	 */
	@Override
	protected void configureShell(Shell newShell) {
		newShell.setMinimumSize(new Point(1000, 550));
		super.configureShell(newShell);
		newShell.setText("ProMo by AnBa & MaHe");
	}

	private List<OverviewProjectsCollection> getTreeViewRootElements() {
		List<OverviewProjectsCollection> rootElements = new ArrayList<OverviewProjectsCollection>();
		rootElements.add(new OverviewProjectsCollection(projectsCollection));
		return rootElements;
	}

	protected DataBindingContext initDataBindings() {
		DataBindingContext bindingContext = new DataBindingContext();
		//
		BeansListObservableFactory treeObservableFactory = new BeansListObservableFactory(
				TreeViewElement.class, "children");
		TreeBeanAdvisor treeAdvisor = new TreeBeanAdvisor(
				TreeViewElement.class, null, "children", null);
		ObservableListTreeContentProvider treeContentProvider = new ObservableListTreeContentProvider(
				treeObservableFactory, treeAdvisor);
		treeViewer.setContentProvider(treeContentProvider);
		//
		treeViewer.setLabelProvider(new TreeObservableLabelProvider(
				treeContentProvider.getKnownElements(), TreeViewElement.class,
				"text", null));
		//
		WritableList writableList = new WritableList(getTreeViewRootElements(),
				TreeViewElement.class);
		treeViewer.setInput(writableList);
		//
		return bindingContext;
	}
}
